<?php
declare(strict_types=1);

namespace service\impl;

use service\exception\ServiceException;
use service\ext\PageData;
use service\service\AdminService;
use service\vo\admin\Admin;
use think\db\BaseQuery;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;

/**
 * 接口实现类
 */
class AdminServiceImpl extends BaseImpl implements AdminService
{

    //当前模块名称
    private static string $modeName = 'admin';



    /**
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws DbException
     * @throws ServiceException
     */
    public function addAdmin(Admin $admin): int
    {
        // TODO: Implement addAdmin() method.
        // 监测用户名是否存在
        $userName = $admin->getUsername();
        $re = $this->getAdminDb()
            ->where(self::$FIELD_ADMIN_USERNAME, $userName)
            ->find();
        if (!empty($re)) {
            throw new ServiceException(self::$modeName, self::ERROR_ADMIN_EXISTS);
        }

        // 添加管理员
        $data = [];
        $data[self::$FIELD_ADMIN_USERNAME] = $userName;
        $data[self::$FIELD_ADMIN_PASSWORD] = md5($admin->getPassword());
        $data[self::$FIELD_ADMIN_ADD_TIME] = date("Y-m-d H:i:s");

        return $this->getAdminDb()->insertGetId($data);
    }

    /**
     * @throws DbException
     */
    public function editAdmin(Admin $admin): int
    {
        // TODO: Implement editAdmin() method.
        // 监测用户名是否存在
        $adminID = $admin->getId();
        // 添加管理员
        $data = [];

        $data[self::$FIELD_ADMIN_STATUS] = $admin->getStatus();
        $data[self::$FIELD_ADMIN_STATUS_REMARK] = $admin->getStatusRemark();

        $password = $admin->getPassword();
        if (!empty($password)) {
            $data[self::$FIELD_ADMIN_PASSWORD] = md5($password);
        }

        return $this->getAdminDb()->where(self::$FIELD_COMMON_ID, $adminID)->update($data);
    }

    /**
     * @throws DbException
     * @throws ServiceException
     */
    public function deleteAdmin(int $id): int
    {
        // TODO: Implement deleteAdmin() method.
        // 判断是否是超级管理员
        $isSuper = $this->getAdminDb()->where(self::$FIELD_COMMON_ID, $id)->value(self::$FIELD_ADMIN_IS_SUPER);
        if ($isSuper == 1) {
            throw new ServiceException(self::$modeName, self::ERROR_ADMIN_DELETE_SUPER);
        }

        //判断是否发布过题目
        $subjectPo = $this->getSubjectDb()
            ->where(self::$FIELD_SUBJECT_U_ID, $id)
            ->where(self::$FIELD_SUBJECT_U_TYPE, 1)
            ->find();
        if(!empty($subjectPo)){
            throw new ServiceException(self::$modeName, self::ERROR_ADMIN_HAS_SUBJECT);
        }

        // 删除管理员
        return $this->getAdminDb()->where(self::$FIELD_COMMON_ID, $id)->delete();
    }

    /**
     * @throws ServiceException
     */
    public function getAdminById(int $id): Admin
    {
        // TODO: Implement getAdminById() method.
        $po = $this->getAdminDb()->where(self::$FIELD_COMMON_ID, $id)->findOrEmpty();
        if(empty($po)){
            throw new ServiceException(self::$modeName, self::ERROR_ADMIN_NOT_EXISTS);
        }
        return $this->getAdminVoFromPo($po);
    }

    /**
     * @throws ModelNotFoundException
     * @throws DataNotFoundException
     * @throws DbException
     */
    public function getAdminsByIds(array $ids): array
    {
        // TODO: Implement getAdminsByIds() method.
        $voList = [];
        $poList = $this->getAdminDb()->whereIn(self::$FIELD_COMMON_ID, $ids)->select();
        if (!empty($voList)) {
            foreach ($poList as $vo) {
                $voList[] = $this->getAdminVoFromPo($vo);
            }
        }
        return $voList;
    }

    /**
     * @throws ModelNotFoundException
     * @throws DbException
     * @throws DataNotFoundException
     * @throws ServiceException
     */
    public function login(string $username, string $password): Admin
    {
        // TODO: Implement login() method.
        $po = $this->getAdminDb()
            ->where(self::$FIELD_ADMIN_USERNAME, $username)
            ->where(self::$FIELD_ADMIN_PASSWORD, md5($password))
            ->find();

        if (empty($po)) {
            throw new ServiceException(self::$modeName, self::ERROR_ADMIN_LOGIN_ERROR);
        }

        if ($po[self::$FIELD_ADMIN_STATUS] == 0) {
            throw new ServiceException(self::$modeName, self::ERROR_ADMIN_LOGIN_STATUS, $po[self::$FIELD_ADMIN_STATUS_REMARK]);
        }

        // 判断角色是否可用
//        if ($po[self::$FIELD_ADMIN_IS_SUPER] == 0) {
//            $roleId = $po[self::$FIELD_ADMIN_USER_ROLE_ID];
//            if (empty($roleId)) {
//                exception(self::ERROR_ADMIN_LOGIN_ADMIN_ROLE_STATUS);
//            }
//
//            $roleStatus = $this->getAdminRoleModel()->where(self::$FIELD_COMMON_ID, $roleId)->value(self::$FIELD_ADMIN_ROLE_STATUS);
//            if ($roleStatus == 0) {
//                exception(self::ERROR_ADMIN_LOGIN_ADMIN_ROLE_STATUS);
//            }
//        }

        return $this->getAdminVoFromPo($po);
    }

    /**
     * @throws ModelNotFoundException
     * @throws DataNotFoundException
     * @throws DbException
     */
    public function searchAdmin(int $currentPage, int $pageSize, array $filterCriteria, array $sorterCriteria): PageData
    {
        // TODO: Implement searchAdmin() method.
        $filter = [];
        if (!empty($filterCriteria)) {
            foreach ($filterCriteria as $key => $value) {
                if (strcasecmp($key, self::$FILTER_NAME) == 0) {
                    //用户名
                    $filter[] = [self::$FIELD_ADMIN_USERNAME, "like", "%{$value}%"];
                } elseif (strcasecmp($key, self::$FILTER_ADD_TIME) == 0) {
                    //时间
                    $betweenTime = makeBetween($value['start'], $value['end']);
                    $filter[] = [self::$FIELD_ADMIN_ADD_TIME, $betweenTime[0], $betweenTime[1]];
                } elseif (strcasecmp($key, self::$FILTER_STATUS) == 0) {
                    //状态
                    $filter[] = [self::$FIELD_ADMIN_STATUS, "=", $value];
                }
            }
        }

        //构建排序条件
        $sort = [];
        if (!empty($sorterCriteria)) {
            foreach ($sorterCriteria as $key => $value) {
                if (strcasecmp($key, self::$SORT_ID) == 0) {
                    $sort[self::$FIELD_COMMON_ID] = $value ? self::$SORT_VALUE_ASC : self::$SORT_VALUE_DESC;
                }
            }
        }
        $count = $this->getAdminDb()
            ->where($filter)
            ->count();

        $list = $this->getAdminDb()
            ->where($filter)
            ->order($sort)
            ->limit($pageSize)
            ->page($currentPage)
            ->select();

        $dataList = [];
        foreach ($list as $po) {
            $dataList[] = $this->getAdminVoFromPo($po);
        }

        $pageData = new PageData();
        $pageData->setData($dataList);
        $pageData->setCount($count);

        return $pageData;
    }


    // *******************************************************私有方法******************************************

    /**
     * 得到管理员对象
     */
    private function getAdminVoFromPo($po): Admin
    {
        $vo = null;
        if (!empty($po)) {
            $vo = new Admin();
            $vo->setId($po[self::$FIELD_COMMON_ID]);
            $vo->setUsername($po[self::$FIELD_ADMIN_USERNAME]);
            $vo->setPassword($po[self::$FIELD_ADMIN_PASSWORD]);
            $vo->setStatus($po[self::$FIELD_ADMIN_STATUS]);
            $vo->setAddTime($po[self::$FIELD_ADMIN_ADD_TIME]);
            $vo->setIsSuper($po[self::$FIELD_ADMIN_IS_SUPER]);
            $vo->setStatusRemark($po[self::$FIELD_ADMIN_STATUS_REMARK]);
        }

        return $vo;
    }
}
